package com.gupao.gupaoeduvippattern.javaBase.a4fanshe.demo3;

import com.gupao.gupaoeduvippattern.javaBase.a4fanshe.demo01.User;
import org.junit.jupiter.api.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author Administrator
 * @date 2020-12-23 22:21
 */
public class Demo01 {


    @Test
    public void test5() throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        Class<UserNew> clazz = UserNew.class;

        //获取所有public的构造器
        Constructor<?>[] constructors = clazz.getConstructors();
        for(Constructor c : constructors){
            System.out.println(c.getModifiers()+","+c.getName());
        }
        System.out.println("**************************");

        //获取所有类型的构造器
        Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
        for(Constructor c :declaredConstructors){
            System.out.println(c.getModifiers()+","+c.getName());
        }

        System.out.println("****************************");
        UserNew userNew = clazz.newInstance();
        Constructor<UserNew> declaredConstructor = clazz.getDeclaredConstructor(String.class, String.class);
        declaredConstructor.setAccessible(true);
        System.out.println(declaredConstructor.newInstance("咕泡", "男"));

    }


    @Test
     public void test4(){
        Class<UserNew> clazz = UserNew.class;

        //获取当前类 和 父类的所有public方法
        Method[] methods = clazz.getMethods();
        for(Method m : methods){
            System.out.println(m.getModifiers()+","+m.getName());
        }
        System.out.println("************************************");
        //获取本类中所有的方法，包括private,default,protected,public
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for(Method m : declaredMethods){
            System.out.println(m.getModifiers()+","+m.getName());
        }

    }


    @Test
    public void test3() throws Exception {
        Class<?> aClass = Class.forName("com.gupao.gupaoeduvippattern.javaBase.a4fanshe.demo3.UserInfoBean");
        UserInfoBean userInfoBean = (UserInfoBean)aClass.newInstance();
        //利用反射设置属性username的值，可以直接访问私有的
        Field username = aClass.getDeclaredField("username");
        username.setAccessible(true);
        username.set(userInfoBean, "咕泡");
        System.out.println(userInfoBean);

        //2、访问私有的方法
        Method privatePrint = aClass.getDeclaredMethod("privatePrint");
        privatePrint.setAccessible(true);
        privatePrint.invoke(userInfoBean);


    }


    @Test
    public void test2() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException {
        Class<?> clazz = Class.forName("com.gupao.gupaoeduvippattern.javaBase.a4fanshe.demo3.UserNew");

        //获取类型中定义的字段，public的字段 或 父类中public的字段
        Field[] fields = clazz.getFields();
        for(Field f : fields){
            System.out.println(f.getModifiers()+" "+f.getName());
        }

        System.out.println("----------------------");
        //可以获取私有的字段，只能够获得当前类中
        Field[] fields2 = clazz.getDeclaredFields();
        for(Field f : fields2){
            System.out.println(f.getModifiers()+" "+f.getName());
        }

        Class<UserNew> userNewClass = UserNew.class;
        UserNew userNew = userNewClass.newInstance();
        //2、对私有属性赋值。获取name字段对应的Field
        Field nameField = userNewClass.getDeclaredField("name");
        nameField.setAccessible(true);
        nameField.set(userNew, "张三");
        System.out.println("userNew.getName()==>"+userNew.getName());

        //对静态属性赋值，在set的时候，不用传入对应对象，只需要传null就可以了
        Field address = userNewClass.getDeclaredField("address");
        address.set(null, "湖南长沙");
        System.out.println(UserNew.address);


    }




    public static void main(String[] args) throws ClassNotFoundException {
//        获取类对象的4种方式
        //方式一
        Class<User> clazz1 = User.class;
        System.out.println(clazz1);
        //方式2
        Class<?> clazz2 = Class.forName("com.gupao.gupaoeduvippattern.javaBase.a4fanshe.demo01.User");
        System.out.println(clazz2);
        //方式3
//        Class<? extends User> clazz3 = new User().getClass();
//        System.out.println(clazz3);
        //方式4
        Class<?> clazz4 = Demo01.class.getClassLoader().loadClass("com.gupao.gupaoeduvippattern.javaBase.a4fanshe.demo01.User");
        System.out.println(clazz4);

        System.out.println("==============2222================");
        //2、获取类的相关结构
        //获取类的修饰符，Integer类型的表示
        /*
         * public  private  protected  static    final  synchronized volatile transient
         *    1       2         4         8       16        32          64      128
         * native  interface  abstract  strict
         *   256      512       1024     2048
         *
         */
        System.out.println(clazz1.getModifiers());
        System.out.println(clazz1.getPackage());
        System.out.println(clazz1.getName());
        System.out.println(clazz1.getSuperclass());
        System.out.println(clazz1.getClassLoader());
        System.out.println(clazz1.getSimpleName());
        //获取类实现的所有接口
        System.out.println(clazz1.getInterfaces().length);
        System.out.println(clazz1.getAnnotations().length);


    }

}
